package org.dxy.trigger.http;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.api.dto.request.*;
import org.dxy.api.dto.request.workorder.BatchDeleteWorkOrderRequest;
import org.dxy.api.dto.request.workorder.CreateWorkOrderRequest;
import org.dxy.api.response.R;
import org.dxy.infrastructure.persistent.db.mybatispuls.po.query.WorkOrderViewPo;
import org.dxy.trigger.http.service.WorkOrderApplicationService;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/api/workorders")
@RequiredArgsConstructor
public class WorkOrderController {
    private final WorkOrderApplicationService workOrderApplicationService;

    /**
     * @description 获取建议的工单编码
     * @return 返回建议的工单编码
     * @date 2025/9/16 23:50
     * @author dxy
     */
    @GetMapping("/suggested-code")
    public R<String> getSuggestedCode() {
        return workOrderApplicationService.getSuggestedCode();
    }

    /**
     * @description 创建工单
     * @param request 包含工单创建信息的请求DTO
     * @return 返回创建成功的工单ID或失败响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @PostMapping
    public R<Long> create(@Validated @RequestBody CreateWorkOrderRequest request) {
        return workOrderApplicationService.create(request);
    }

    /**
     * @description 分页查询工单列表（支持条件过滤）
     * @param page 分页参数（页码、每页大小等）
     * @param query 过滤条件（工单编码、产品型号、状态等）
     * @return 分页的工单列表响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @GetMapping("/list")
    public R<Page<WorkOrderViewPo>> list(
            @ParameterObject Page<WorkOrderViewPo> page,
            @ParameterObject WorkOrderViewPo query) {
        return workOrderApplicationService.list(page, query);
    }

    /**
     * @description 查询工单详情
     * @param workOrderId 工单ID
     * @return 返回工单详情或失败响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @GetMapping("/{workOrderId}")
    public R<WorkOrderViewPo> getById(@PathVariable Long workOrderId) {
        return workOrderApplicationService.getById(workOrderId);
    }

    /**
     * @description 根据状态分页查询工单
     * @param page 分页参数
     * @param status 工单状态
     * @return 分页的工单列表响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @GetMapping("/status/{status}")
    public R<Page<WorkOrderViewPo>> getByStatus(
            @ParameterObject Page<WorkOrderViewPo> page,
            @PathVariable String status) {
        return workOrderApplicationService.getByStatus(page, status);
    }

    /**
     * @description 下达工单
     * @param workOrderId 工单ID
     * @return 返回下达成功或失败的响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @PostMapping("/{workOrderId}/release")
    public R<Void> release(@PathVariable Long workOrderId) {
        return workOrderApplicationService.release(workOrderId);
    }

    /**
     * @description 开始工单生产
     * @param workOrderId 工单ID
     * @return 返回开始成功或失败的响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @PostMapping("/{workOrderId}/start")
    public R<Void> start(@PathVariable Long workOrderId) {
        return workOrderApplicationService.start(workOrderId);
    }

    /**
     * @description 暂停工单
     * @param workOrderId 工单ID
     * @param request 包含暂停原因的请求DTO
     * @return 返回暂停成功或失败的响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @PostMapping("/{workOrderId}/suspend")
    public R<Void> suspend(@PathVariable Long workOrderId, 
                          @Validated @RequestBody SuspendWorkOrderRequest request) {
        return workOrderApplicationService.suspend(workOrderId, request);
    }

    /**
     * @description 恢复工单生产
     * @param workOrderId 工单ID
     * @return 返回恢复成功或失败的响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @PostMapping("/{workOrderId}/resume")
    public R<Void> resume(@PathVariable Long workOrderId) {
        return workOrderApplicationService.resume(workOrderId);
    }

    /**
     * @description 完成工单
     * @param workOrderId 工单ID
     * @param request 包含完成数量的请求DTO
     * @return 返回完成成功或失败的响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @PostMapping("/{workOrderId}/complete")
    public R<Void> complete(@PathVariable Long workOrderId,
                           @Validated @RequestBody CompleteWorkOrderRequest request) {
        return workOrderApplicationService.complete(workOrderId, request);
    }

    /**
     * @description 关闭工单
     * @param workOrderId 工单ID
     * @param request 包含关闭原因的请求DTO
     * @return 返回关闭成功或失败的响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @PostMapping("/{workOrderId}/close")
    public R<Void> close(@PathVariable Long workOrderId,
                        @Validated @RequestBody CloseWorkOrderRequest request) {
        return workOrderApplicationService.close(workOrderId, request);
    }

    /**
     * @description 取消工单
     * @param workOrderId 工单ID
     * @param request 包含取消原因的请求DTO
     * @return 返回取消成功或失败的响应
     * @date 2025/7/25 20:01
     * @author dxy
     */
    @PostMapping("/{workOrderId}/cancel")
    public R<Void> cancel(@PathVariable Long workOrderId,
                         @Validated @RequestBody CancelWorkOrderRequest request) {
        return workOrderApplicationService.cancel(workOrderId, request);
    }

    /**
     * @description 更新工单信息
     * @param workOrderId 工单ID，必须为正整数
     * @param request 包含工单更新信息的请求DTO，包括工单编码、产品型号、计划数量等
     * @return 返回更新成功或失败的响应
     * @throws IllegalArgumentException 当工单ID无效时抛出
     * @date 2025/7/31 20:01
     * @author dxy
     */
    @PutMapping("/{workOrderId}")
    public R<Void> update(@PathVariable("workOrderId") Long workOrderId,
                         @Validated @RequestBody CreateWorkOrderRequest request) {
        log.info("更新工单请求 - 工单ID: {}, 请求参数: {}", workOrderId, request);
        
        if (workOrderId == null || workOrderId <= 0) {
            log.warn("无效的工单ID: {}", workOrderId);
            return R.fail("工单ID不能为空且必须为正整数");
        }
        
        try {
            R<Void> result = workOrderApplicationService.update(workOrderId, request);
//            if (result.isSuccess()) {
//                log.info("工单更新成功 - 工单ID: {}", workOrderId);
//            } else {
//                log.warn("工单更新失败 - 工单ID: {}, 错误信息: {}", workOrderId, result.getMsg());
//            }
            return result;
        } catch (Exception e) {
            log.error("工单更新异常 - 工单ID: {}", workOrderId, e);
            return R.fail("工单更新失败: " + e.getMessage());
        }
    }

    /**
     * @description 删除单个工单
     * @param workOrderId 工单ID，必须为正整数
     * @return 返回删除成功或失败的响应
     * @throws IllegalArgumentException 当工单ID无效时抛出
     * @apiNote 只有处于已创建、已取消、已关闭状态的工单才能被删除
     * @date 2025/7/31 20:01
     * @author dxy
     */
    @DeleteMapping("/{workOrderId}")
    public R<Void> delete(@PathVariable("workOrderId") Long workOrderId) {
        log.info("删除工单请求 - 工单ID: {}", workOrderId);
        
        if (workOrderId == null || workOrderId <= 0) {
            log.warn("无效的工单ID: {}", workOrderId);
            return R.fail("工单ID不能为空且必须为正整数");
        }
        
        try {
            R<Void> result = workOrderApplicationService.delete(workOrderId);
            if (result.isOk()) {
                log.info("工单删除成功 - 工单ID: {}", workOrderId);
            } else {
                log.warn("工单删除失败 - 工单ID: {}, 错误信息: {}", workOrderId, result.getMsg());
            }
            return result;
        } catch (Exception e) {
            log.error("工单删除异常 - 工单ID: {}", workOrderId, e);
            return R.fail("工单删除失败: " + e.getMessage());
        }
    }

    /**
     * @description 批量删除工单
     * @param request 包含工单ID列表的请求DTO，ID列表不能为空且每个ID必须为正整数
     * @return 返回批量删除成功或失败的响应
     * @throws IllegalArgumentException 当请求参数无效时抛出
     * @apiNote 只有处于已创建、已取消、已关闭状态的工单才能被删除，如果列表中包含不可删除的工单，整个操作将失败
     * @date 2025/7/31 20:01
     * @author dxy
     */
    @DeleteMapping("/batch")
    public R<Void> batchDelete(@Validated @RequestBody BatchDeleteWorkOrderRequest request) {
        log.info("批量删除工单请求 - 工单ID列表: {}", request.getIds());
        
        if (request.getIds() == null || request.getIds().isEmpty()) {
            log.warn("批量删除请求参数无效: 工单ID列表为空");
            return R.fail("工单ID列表不能为空");
        }
        
        // 验证ID列表中的每个ID都是有效的正整数
        for (Long id : request.getIds()) {
            if (id == null || id <= 0) {
                log.warn("批量删除请求参数无效: 包含无效的工单ID {}", id);
                return R.fail("工单ID列表中包含无效的ID: " + id);
            }
        }
        
        if (request.getIds().size() > 100) {
            log.warn("批量删除请求参数无效: 一次删除的工单数量过多 {}", request.getIds().size());
            return R.fail("一次最多只能删除100个工单");
        }
        
        try {
            R<Void> result = workOrderApplicationService.batchDelete(request.getIds());
//            if (result.isSuccess()) {
//                log.info("批量删除工单成功 - 删除数量: {}", request.getIds().size());
//            } else {
//                log.warn("批量删除工单失败 - 工单ID列表: {}, 错误信息: {}", request.getIds(), result.getMsg());
//            }
            return result;
        } catch (Exception e) {
            log.error("批量删除工单异常 - 工单ID列表: {}", request.getIds(), e);
            return R.fail("批量删除工单失败: " + e.getMessage());
        }
    }
}
